package com.behealthy.util;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.math.BigInteger;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Hashtable;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.app.Application;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.net.http.AndroidHttpClient;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Log;

import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.Facebook;

public class Utility extends Application {

    public static Facebook mFacebook;
    public static AsyncFacebookRunner mAsyncRunner;
    public static JSONObject mFriendsList;
    public static String userUID = null;
    public static String objectID = null;
   // public static FriendsGetProfilePics model;
    public static AndroidHttpClient httpclient = null;
    public static Hashtable<String, String> currentPermissions = new Hashtable<String, String>();

    private static int MAX_IMAGE_DIMENSION = 720;
    public static final String APP_ICON_URL = "http://mantugaul.files.wordpress.com/2009/08/magratheaicon.png";
    

    public static Bitmap getBitmap(String url) {
        Bitmap bm = null;
        try {
            URL aURL = new URL(url);
            URLConnection conn = aURL.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            bm = BitmapFactory.decodeStream(new FlushedInputStream(is));
            bis.close();
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (httpclient != null) {
                httpclient.close();
            }
        }
        return bm;
    }

    static class FlushedInputStream extends FilterInputStream {
        public FlushedInputStream(InputStream inputStream) {
            super(inputStream);
        }

        @Override
        public long skip(long n) throws IOException {
            long totalBytesSkipped = 0L;
            while (totalBytesSkipped < n) {
                long bytesSkipped = in.skip(n - totalBytesSkipped);
                if (bytesSkipped == 0L) {
                    int b = read();
                    if (b < 0) {
                        break; // we reached EOF
                    } else {
                        bytesSkipped = 1; // we read one byte
                    }
                }
                totalBytesSkipped += bytesSkipped;
            }
            return totalBytesSkipped;
        }
    }

    public static byte[] scaleImage(Context context, Uri photoUri) throws IOException {
        InputStream is = context.getContentResolver().openInputStream(photoUri);
        BitmapFactory.Options dbo = new BitmapFactory.Options();
        dbo.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(is, null, dbo);
        is.close();

        int rotatedWidth, rotatedHeight;
        int orientation = getOrientation(context, photoUri);

        if (orientation == 90 || orientation == 270) {
            rotatedWidth = dbo.outHeight;
            rotatedHeight = dbo.outWidth;
        } else {
            rotatedWidth = dbo.outWidth;
            rotatedHeight = dbo.outHeight;
        }

        Bitmap srcBitmap;
        is = context.getContentResolver().openInputStream(photoUri);
        if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) {
            float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION);
            float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION);
            float maxRatio = Math.max(widthRatio, heightRatio);

            // Create the bitmap from file
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = (int) maxRatio;
            srcBitmap = BitmapFactory.decodeStream(is, null, options);
        } else {
            srcBitmap = BitmapFactory.decodeStream(is);
        }
        is.close();

        /*
         * if the orientation is not 0 (or -1, which means we don't know), we
         * have to do a rotation.
         */
        if (orientation > 0) {
            Matrix matrix = new Matrix();
            matrix.postRotate(orientation);

            srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),
                    srcBitmap.getHeight(), matrix, true);
        }

        String type = context.getContentResolver().getType(photoUri);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        if (type.equals("image/png")) {
            srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        } else if (type.equals("image/jpg") || type.equals("image/jpeg")) {
            srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        }
        byte[] bMapArray = baos.toByteArray();
        baos.close();
        return bMapArray;
    }

    public static int getOrientation(Context context, Uri photoUri) {
        /* it's on the external media. */
        Cursor cursor = context.getContentResolver().query(photoUri,
                new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);

        if (cursor.getCount() != 1) {
            return -1;
        }

        cursor.moveToFirst();
        return cursor.getInt(0);
    }
    
    
	public static String CallWebService(String url, String soapAction, String envelope) {

		final DefaultHttpClient httpClient = new DefaultHttpClient();

		// Request parameters
		HttpParams params = httpClient.getParams();
		HttpConnectionParams.setConnectionTimeout(params, 10000);
		HttpConnectionParams.setSoTimeout(params, 15000);
		// Set parameter
		HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), true);

		// POST the envelope
		HttpPost httppost = new HttpPost(url);

		// Add headers
		httppost.setHeader("soapaction", soapAction);
		httppost.setHeader("Content-Type", "text/xml; charset=utf-8");

		String responseString = "";
		try {

			// The entity holds the request
			HttpEntity entity = new StringEntity(envelope);
			httppost.setEntity(entity);

			// Response handler
			ResponseHandler<String> rh = new ResponseHandler<String>() {

				// Invoked when client receives response
				public String handleResponse(HttpResponse response)
						throws ClientProtocolException, IOException {

					// Get response entity
					HttpEntity entity = response.getEntity();

					// Read the response as byte array
					StringBuffer out = new StringBuffer();
					byte[] b = EntityUtils.toByteArray(entity);

					// Write the response byte array to a string buffer
					out.append(new String(b, 0, b.length));
					return out.toString();
				}
			};

			responseString = httpClient.execute(httppost, rh);

		} catch (Exception e) {
			Log.v("exception", e.toString());
		}

		// Close the connection
		httpClient.getConnectionManager().shutdown();
		return responseString;
	}
	
	public static String parseByDOM(String response, String myAction)
			throws ParserConfigurationException, SAXException, IOException {

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		Document doc = db.parse(new InputSource(new StringReader(response)));
		
		String s = "";

		// Normalize the document
		doc.getDocumentElement().normalize();

		// Get the root node
		NodeList nodeList = doc.getElementsByTagName("S:Envelope");
		Node envelope = nodeList.item(0);

		Log.d("Root", envelope.getNodeName());

		Node temp, body, action, success, message;
		body = null;
		action = null;
		success = null;
		message = null;
		int i;

		// Get the body node from all the children of the root
		for (i = 0; i < envelope.getChildNodes().getLength() && body == null; i++) {
			temp = envelope.getChildNodes().item(i);
			if (temp.getNodeName().equalsIgnoreCase("s:body"))
				body = temp;
		}

		Log.d("Body", body.getNodeName());

		// Get the login node from all the children of the body
		for (i = 0; i < body.getChildNodes().getLength() && action == null; i++) {
			temp = body.getChildNodes().item(i);
			if (temp.getNodeName().equalsIgnoreCase("ns2:"+myAction))
				action = temp;
		}

		

		// Get the success node from all the children of the loginResponse node
		for (i = 0; i < action.getChildNodes().getLength() && success == null; i++) {
			temp = action.getChildNodes().item(i);
			if (temp.getNodeName().equalsIgnoreCase("success"))
				success = temp;
			if (temp.getNodeName().equalsIgnoreCase("message"))
				message = temp;
		}

		
		String value = success.getTextContent();
		String msg = message.getTextContent();
		
		
		if (value.equalsIgnoreCase("true")) 
			 s = value;
		else s = msg;
						
		return s;
	}
	
    public static boolean parseByDOM2 (String response)
			throws ParserConfigurationException, SAXException, IOException {
    	
    	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		Document doc = db.parse(new InputSource(new StringReader(response)));
		boolean bool = false;

		// Normalize the document
		doc.getDocumentElement().normalize();

		// Get the root node
		NodeList nodeList = doc.getElementsByTagName("S:Envelope");
		Node envelope = nodeList.item(0);

		Log.d("Root", envelope.getNodeName());

		@SuppressWarnings("unused")
		Node temp, body, checkCategorii, success = null;
		String mesaj = null;
		body = null;
		checkCategorii = null;
		int i;

		// Get the body node from all the children of the root
		for (i = 0; i < envelope.getChildNodes().getLength() && body == null; i++) {
			temp = envelope.getChildNodes().item(i);
			if (temp.getNodeName().equalsIgnoreCase("s:body"))
				body = temp;
		}

		Log.d("Body", body.getNodeName());
 
		// Get the checkCategorii node from all the children of the body
		for (i = 0; i < body.getChildNodes().getLength() && checkCategorii == null; i++) {
			temp = body.getChildNodes().item(i);
			if (temp.getNodeName().equalsIgnoreCase("ns2:checkCategoriiResponse"))
				checkCategorii = temp;
		}

		// Get the mesaj node from all the children of the selectNume node
		for (i = 0; i < checkCategorii.getChildNodes().getLength() ; i++) {
			temp = checkCategorii.getChildNodes().item(i);
			if (temp.getNodeName().equalsIgnoreCase("message"))
				mesaj = temp.getTextContent();
			if(temp.getNodeName().equalsIgnoreCase("success"))
				success = temp;
		}
		
		if (mesaj.equals("Lista s-a modificat ")) {
			bool = true;	
		}
		return bool;
    }
    
    public static String encryptPassword (String password) {
    	String passwordEncrypt = null;
    	try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(password.getBytes(), 0, password.length());
			passwordEncrypt= new BigInteger(1, md.digest()).toString(16);
			Log.d("MD5 encryption", passwordEncrypt);
		} catch (NoSuchAlgorithmException e) {
			
			e.printStackTrace();
		}
    	return passwordEncrypt;
    }
    
    public static String register(String fnameStr, String lnameStr,
    		String emailStr, String passwordEncrypt,
    		String username, Date birthdate, String url) {
    	String envelope = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+
				"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
				"xmlns:ws=\"http://ws.android/\">"+
				  "<soapenv:Header/>" +
				  "<soapenv:Body>"+
				    "<ws:insertAccount>"+
				    "<username>%s</username>"+
				    "<password>%s</password>"+
				    "<person>"+		
				      "<firstName>%s</firstName>"+
				      "<lastName>%s</lastName>"+
				      "<email>%s</email>";
		String envelope2="<birthDate>%1$tY-%1$tm-%1$teT%1$tH:%1$tM:%1$tS.%1$tS0</birthDate>"+
				      "</person>"+
				    "</ws:insertAccount>"+
				  "</soapenv:Body>"+
				"</soapenv:Envelope>";
		
		String requestEnvelope = 
				String.format(envelope, username, passwordEncrypt, fnameStr, 
						lnameStr, emailStr)+ 
				String.format(envelope2, birthdate);
		
		Log.d("Envelope", requestEnvelope);
		
		String soapAction = "insertAccount";
		String response = "message";
		response = Utility.CallWebService(url, soapAction, requestEnvelope);
    	return response;
    }
    
    public static String getNumeCategoriiEnvelope () {
    	 String envelope = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
 				+ "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "
 				+ "xmlns:ws=\"http://ws.android/\">"
 				+ "<soapenv:Header/>"
 				+ "<soapenv:Body>"
 				+ "</soapenv:Body>" 
 				+ "</soapenv:Envelope>";
    	 return envelope;
    }
    
    public static Bitmap Base64ToBitmap(String encodedImage)
    {
    	// Convert Base64 String to byte[]
    	byte[] decodedString = Base64.decode(encodedImage, Base64.DEFAULT);
    	Bitmap decodedImage = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
      
        return decodedImage;
    }
    
//    public static GeoPoint getPoint(double lat, double lon) {
//	    return(new GeoPoint((int)(lat* 1E6),
//	                          (int)(lon* 1E6)));
//	  }
}
